﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.Mvc;
using System.Web.Routing;

namespace MvcEngine.Mvc.Filters
{
    public class RedirectToActionOnErrorAttribute : RedirectOnErrorAttribute
    {
        #region Public properties

        public Type Controller { get; set; }
        public string Action { get; set; } 

        #endregion

        #region Protected methods
        protected override bool Validate(ExceptionContext exceptionContext)
        {
            if (Controller == null || (string.IsNullOrEmpty(Action) || Action.Trim() == string.Empty))
                throw new ArgumentNullException("RedirectToUrlOnActionAttribute's Controller and Action properties must have values.");

            if (!typeof(Controller).IsAssignableFrom(Controller))
                throw new ArgumentException("RedirectToUrlOnActionAttribute's Controller property's value must derive from System.Web.Mvc.Controller.");

            return true;
        }

        protected override void Redirect(ExceptionContext exceptionContext)
        {
            string controllerName = Controller.ToString();
            controllerName = controllerName.Substring(controllerName.LastIndexOf(".") + 1);
            controllerName = controllerName.Substring(0, controllerName.LastIndexOf("Controller"));

            RouteValueDictionary rvd = new RouteValueDictionary(new
            {
                controller = controllerName,
                action = Action
            });

            RequestContext context = new RequestContext(exceptionContext.HttpContext, exceptionContext.RouteData);

            VirtualPathData vpd = RouteTable.Routes.GetVirtualPath(context, rvd);
            string url = vpd.VirtualPath;

            exceptionContext.ExceptionHandled = true;
            exceptionContext.HttpContext.Response.Redirect(url, true);
        } 
        #endregion
    }
}
